package com.monkey.service;

import com.google.common.cache.*;
import com.monkey.generator.dao.*;
import com.monkey.generator.model.*;
import com.monkey.model.comparator.MonkeyMyBonusComparator;
import com.monkey.model.comparator.MonkeyMyGenerationComparator;
import com.monkey.model.comparator.MonkeyMySort;
import com.monkey.model.comparator.MonkeyMyWeightComparator;
import com.monkey.model.comparator.MonkeyMyGrowComparator;
import com.monkey.model.comparator.MonkeyMyProfitComparator;
import com.monkey.model.comparator.MonkeyMyReproductComparator;
import com.monkey.model.monkey.*;
import com.monkey.model.user.User;
import com.monkey.util.*;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.math.BigDecimal;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.List;
import java.util.concurrent.TimeUnit;

import static com.monkey.service.UserService.*;

/**
 * desc: auth: chenxiaobin data: 2018/1/4.
 */
@Service
@Transactional
public class MonkeyService {
	private static Logger logger = LoggerFactory.getLogger(MonkeyService.class);
	public static final int MONKEY_STATUS_NORMAL = 0; // 状态正常
	public static final int MONKEY_STATUS_FEED = 1; // 状态喂食中
	public static final int MONKEY_STATUS_MARKET = 2; // 状态交易中
	public static final int MONKEY_STATUS_MARRY = 3; // 状态交配中
	public static final int MONKEY_STATUS_SYNTHESISE = 4; // 已被合成
	
	public static final int MONKEY_FROM_SYSTEM = 1; // 系统赠送
	public static final int MONKEY_FROM_MARKET = 2; // 交易
	public static final int MONKEY_FROM_MARRY = 3; // 交配
	public static final int MONKEY_FROM_ADMIN = 4; // 后台赠送
	public static final int MONKEY_FROM_LUCK = 5; // 抽奖
	private LoadingCache<Integer, Monkey> monkeyCache;
	private int monkeyIndex;

	@Resource
	private UserService userService = null;

	@Resource
	private MonkeyBoneService monkeyBoneService = null;

	@Resource
	private MarketService marketService = null;

	@Resource
	private MarryService marryService = null;

	@Resource
	private TMonkeyMapper monkeyMapper = null;

	@Resource
	private TMonkeyCreateMapper monkeyCreateMapper = null;

	@Resource
	private TMonkeyFeedMapper monkeyFeedMapper = null;

	@Resource
	private TUserFeedMapper userFeedMapper = null;

	@Resource
	private TUserMonkeyMapper userMonkeyMapper = null;

	@Resource
	private TMonkeyBonusMapper monkeyBonusMapper = null;

	@Resource
	private TMonkeyReproductMapper monkeyReproductMapper = null;

	@Resource
	private TMarketOrderMapper marketOrderMapper = null;

	@Resource
	private TMarryOrderMapper marryOrderMapper = null;

	@Resource
	private HelpUtil limitUtil = null;

	@Resource
	private CountUtil countUtil = null;

	@Resource
	private IDGenerator idGenerator = null;

	@Resource
	private DateUtil dateUtil = null;

	@Resource
	private WebConfig webConfig = null;
	
	@Resource
	private TUserSynthesiseMapper userSynthesiseMapper = null;

	public void init() {
		monkeyBoneService.init();
		initMonkeyIndex();
		initCache();
	}

	public boolean initNewUser(User user) {
		int min = webConfig.getInt("monkey.create.min");
		int max = webConfig.getInt("monkey.create.max");
		int num = webConfig.getInt("monkey.create.num");
		for (int i = 0; i < num; ++i) {
			// 代数
			int g = min + (int) (Math.random() * (max - min + 1));
			MonkeyCreate create = createData();
			Monkey monkey = create(g, 0, 0, user, MONKEY_FROM_SYSTEM, null, create, null);
			if (null == monkey) {
				return false;
			}

			TMonkeyCreate create1 = new TMonkeyCreate();
			create1.setMonkeyid(monkey.getId());
			create1.setUuid(create.getUuid());
			create1.setCreatetime(new Date());
			if (0 == monkeyCreateMapper.insert(create1)) {
				logger.info("monkey create db error:{}, {}", monkey.getId(), create.getUuid());
			}
		}
		return true;
	}

	/**
	 * 获取自己的宠物列表
	 *
	 * @param userId
	 *            用户id
	 * @param sort
	 *            排序
	 * @param status
	 *            筛选状态，0全部，1正常，2交易中，3生育中, 4已被合成
	 * @param element
	 *            筛选宠物五行，-1全部，[0-4]
	 * @param show
	 *            是否显示价格，不显示的必然是全部状态
	 */
	public List<MonkeyData> getList(int userId, MonkeyMySort sort, int status, int element) {
		TUserMonkeyExample example = new TUserMonkeyExample();
		example.or().andUseridEqualTo(userId);
		List<TUserMonkey> monkeys = userMonkeyMapper.selectByExample(example);
		if (null == monkeys || monkeys.isEmpty()) {
			return new ArrayList<>();
		}

		SimpleDateFormat sdf = dateUtil.getDateFormat();
		List<MonkeyData> monkeyList = new ArrayList<>();
		switch (status) {
		case 1:
			for (TUserMonkey m : monkeys) {
				Monkey monkey = getMonkey(m.getMonkeyid());
				if (null != monkey && monkey.getStatus() != MONKEY_STATUS_MARKET
						&& monkey.getStatus() != MONKEY_STATUS_MARRY
						&& monkey.getStatus() != MONKEY_STATUS_SYNTHESISE
						&& (element == -1 || monkey.getElement() == element)) {
					if (element == -1 || monkey.getElement() == element) {
						MonkeyData data = new MonkeyData(monkey, sdf);
						monkeyList.add(data);
					}
				}
			}
			break;

		case 2:
			for (TUserMonkey m : monkeys) {
				Monkey monkey = getMonkey(m.getMonkeyid());
				if (null != monkey && monkey.getStatus() == MONKEY_STATUS_MARKET
						&& monkey.getStatus() != MONKEY_STATUS_SYNTHESISE) {
					if (element == -1 || monkey.getElement() == element) {
						MonkeyData data = new MonkeyData(monkey, sdf);
						data.setPrice(marketService.getPrice(m.getMonkeyid()));
						monkeyList.add(data);
					}
				}
			}
			break;

		case 3:
			for (TUserMonkey m : monkeys) {
				Monkey monkey = getMonkey(m.getMonkeyid());
				if (null != monkey && monkey.getStatus() == MONKEY_STATUS_MARRY
						&& monkey.getStatus() != MONKEY_STATUS_SYNTHESISE) {
					if (element == -1 || monkey.getElement() == element) {
						MonkeyData data = new MonkeyData(monkey, sdf);
						data.setPrice(marryService.getPrice(m.getMonkeyid()));
						monkeyList.add(data);
					}
				}
			}
			break;

		default:
			for (TUserMonkey m : monkeys) {
				Monkey monkey = getMonkey(m.getMonkeyid());
				if (null != monkey) {
					if(monkey.getStatus() != MONKEY_STATUS_SYNTHESISE){
						if (element == -1 || monkey.getElement() == element) {
							MonkeyData data = new MonkeyData(monkey, sdf);
							if (MONKEY_STATUS_MARKET == data.getStatus()) {
								data.setPrice(marketService.getPrice(m.getMonkeyid()));
							} else if (MONKEY_STATUS_MARRY == data.getStatus()) {
								data.setPrice(marryService.getPrice(m.getMonkeyid()));
							}
							monkeyList.add(data);
						}
					}
				}
			}
		}

		// 收益排序
		if (sort.isProfit()) {
			monkeyList.sort(new MonkeyMyProfitComparator(sort.getProfit()));
			if (!limitUtil.getListWithMonkeyData(monkeyList, sort.getOffset(), sort.getNum())) {
				return new ArrayList<>();
			}
			return monkeyList;
		}
		
		// 代数排序
		if (sort.isGeneration()) {
			monkeyList.sort(new MonkeyMyGenerationComparator(sort.getGeneration()));
			if (!limitUtil.getListWithMonkeyData(monkeyList, sort.getOffset(), sort.getNum())) {
				return new ArrayList<>();
			}
			return monkeyList;
		}

		// 体重排序
		if (sort.isWeight()) {
			monkeyList.sort(new MonkeyMyWeightComparator(sort.getWeight()));
			if (!limitUtil.getListWithMonkeyData(monkeyList, sort.getOffset(), sort.getNum())) {
				return new ArrayList<>();
			}
			return monkeyList;
		}

		// 掘金排序
		if (sort.isBonus()) {
			monkeyList.sort(new MonkeyMyBonusComparator(sort.getBonus()));
			if (!limitUtil.getListWithMonkeyData(monkeyList, sort.getOffset(), sort.getNum())) {
				return new ArrayList<>();
			}
			return monkeyList;
		}
		
		// 成长排序
		if (sort.isGrow()) {
			monkeyList.sort(new MonkeyMyGrowComparator(sort.getGrow()));
			if (!limitUtil.getListWithMonkeyData(monkeyList, sort.getOffset(), sort.getNum())) {
				return new ArrayList<>();
			}
			return monkeyList;
		}
				
		// 生育排序
		if (sort.isReproduct()) {
			monkeyList.sort(new MonkeyMyReproductComparator(sort.getReproduct()));
			if (!limitUtil.getListWithMonkeyData(monkeyList, sort.getOffset(), sort.getNum())) {
				return new ArrayList<>();
			}
			return monkeyList;
		}

		// 默认排序
		monkeyList.sort(new MonkeyMyGenerationComparator(true));
		if (!limitUtil.getListWithMonkeyData(monkeyList, sort.getOffset(), sort.getNum())) {
			return new ArrayList<>();
		}
		return monkeyList;
	}

	public MonkeyCreate createData() {
		int grow = (int) (Math.random() * 16);
		int reproduct = (int) (Math.random() * 16);
		int bonus = (int) (Math.random() * 16);
		return createData(grow, reproduct, bonus);
	}

	public MonkeyCreate createData(int grow, int reproduct, int bonus) {
		String uuid = idGenerator.randomUUID();
		uuid = uuid.substring(0, uuid.length() - 3);
		uuid += String.format("%x", grow);
		uuid += String.format("%x", reproduct);
		uuid += String.format("%x", bonus);

		grow = grow % 10;
		reproduct = reproduct % 10;
		bonus = bonus % 10;
		return new MonkeyCreate(grow, reproduct, bonus, uuid);
	}

	// 系统产生
	public Monkey create(int generation, int dadId, int momId, User user, int action, Integer uuid1, MonkeyCreate data,
			MonkeySpecify specify) {
		int userId = user.getId();
		int monkeyId;
		if (null == specify || 0 == specify.getId()) {
			synchronized (this) {
				monkeyId = ++monkeyIndex;
			}
		} else {
			monkeyId = specify.getId();
		}
		logger.info("create monkey:{}, {}, {}, {}, {}", monkeyId, userId, generation, dadId, momId);

		int grow = 100 + data.getGrow() * 10;
		int reproduct = 100 + data.getReproduct() * 10;
		int bonus = 100 + data.getBonus() * 10;

		BigDecimal dec = new BigDecimal(0);
		Date now = new Date();
		TMonkey monkey = new TMonkey();
		monkey.setMonkeyid(monkeyId);
		monkey.setDadid(dadId);
		monkey.setMonid(momId);
		monkey.setGeneration(generation);
		monkey.setWeight(0);
		monkey.setGroworigin(grow);
		monkey.setReproductorigin(reproduct);
		monkey.setBonusorigin(bonus);
		monkey.setGrow(grow);
		monkey.setReproduct(reproduct);
		monkey.setBonus(bonus);
		monkey.setReproductcount(0);
		monkey.setBonuscount(0);
		monkey.setBonusyesterday(dec);
		monkey.setBonustotal(dec);
		monkey.setElement(monkeyId % 5);
		monkey.setCreatetime(now);

		if (null != specify && 0 != specify.getGrow()) {
			monkey.setGroworigin(specify.getGrow());
			monkey.setReproductorigin(specify.getReproduct());
			monkey.setBonusorigin(specify.getBonus());
			monkey.setGrow(specify.getGrow());
			monkey.setReproduct(specify.getReproduct());
			monkey.setBonus(specify.getBonus());
		}

		// 生育时间 = 标准生育时间 *（1+生育系数）^（已生育次数）* 代系数 / (1+生育值^2/10)
		int base = webConfig.getInt("monkey.reproduct.base");
		float r = monkey.getReproduct() * 1.0f / 100;
		int sonCD = (int) (base * countUtil.generation(generation) / (1 + Math.pow(r, 3) / 10));
		logger.info("marry son:{}, r:{}, {} * 1 * {} / (1 + {} / 10) = {}", generation, r, base,
				countUtil.generation(generation), Math.pow(r, 3), sonCD);

		Calendar calendar = Calendar.getInstance();
		calendar.setTime(now);
		calendar.add(Calendar.MINUTE, sonCD);
		monkey.setReproductcd(calendar.getTime());

		// 形象
		if (null != uuid1) {
			if (null != specify) {
				monkey.setUuid(monkeyBoneService.getUuid(uuid1, specify.getUuid2()));
			} else {
				monkey.setUuid(monkeyBoneService.getUuid(uuid1, 0));
			}
		} else {
			monkey.setUuid(monkeyBoneService.getUuid(0, 0));
		}

		if (0 == monkeyMapper.insert(monkey)) {
			logger.error("create monkey error:{}", monkeyId);
			return null;
		}

		Monkey monkey1 = new Monkey(monkey);
		addMonkeyCache(monkey1);

		// 关联
		TUserMonkey userMonkey = new TUserMonkey();
		userMonkey.setUserid(userId);
		userMonkey.setMonkeyid(monkeyId);
		userMonkey.setAction(action);
		userMonkey.setData1(0);
		userMonkey.setData2(0);
		userMonkey.setData3(0);
		userMonkey.setStatus(MONKEY_STATUS_NORMAL);
		userMonkey.setCreatetime(now);
		if (0 == userMonkeyMapper.insert(userMonkey)) {
			logger.error("create monkey link user error:{}", monkeyId);
			return null;
		}

		// 插入喂食记录
		SimpleDateFormat sdf = dateUtil.getSimpleDateFormat();
		TMonkeyFeed feed = new TMonkeyFeed();
		feed.setMonkeyid(monkeyId);
		feed.setCount(0);
		feed.setMoney(0);
		feed.setFeedtime(sdf.format(now));
		feed.setCreatetime(now);
		if (0 == monkeyFeedMapper.insert(feed)) {
			logger.info("monkey init feed error:{}, {}", userId, monkeyId);
		}

		userService.updateUserHead(user, monkey1);
		monkey1.setUserInfo(userId);
		user.setMonkeyNum(user.getMonkeyNum() + 1);
		return monkey1;
	}

	public List<MonkeyOrder> getOrderList(int userId, int status, int offset, int num) {
		List<MonkeyOrder> ret = new ArrayList<>();
		switch (status) {
		case ORDER_HISTORY_SELLIN: {
			TMarketOrderExample example = new TMarketOrderExample();
			example.or().andTouseridEqualTo(userId);
			example.setOrderByClause("createTime DESC");
			example.setOffset(offset);
			example.setLimit(num);
			List<TMarketOrder> orders = marketOrderMapper.selectByExample(example);
			if (null == orders || orders.isEmpty()) {
				return ret;
			}
			SimpleDateFormat sdf = dateUtil.getDateFormat();
			for (TMarketOrder o : orders) {
				int monkeyId = o.getMonkeyid();
				Monkey monkey = getMonkey(monkeyId);
				if (null != monkey) {
					ret.add(new MonkeyOrder(monkeyId, MONKEY_STATUS_MARKET, monkey.getUuid(), o.getMoney(),
							o.getStatus(), o.getCreatetime(), sdf));
				}
			}
		}
			break;

		case ORDER_HISTORY_SELLOUT: {
			TMarketOrderExample example = new TMarketOrderExample();
			example.or().andUseridEqualTo(userId);
			example.setOrderByClause("createTime DESC");
			example.setOffset(offset);
			example.setLimit(num);
			List<TMarketOrder> orders = marketOrderMapper.selectByExample(example);
			if (null == orders || orders.isEmpty()) {
				return ret;
			}
			SimpleDateFormat sdf = dateUtil.getDateFormat();
			for (TMarketOrder o : orders) {
				int monkeyId = o.getMonkeyid();
				Monkey monkey = getMonkey(monkeyId);
				if (null != monkey) {
					ret.add(new MonkeyOrder(monkeyId, MONKEY_STATUS_MARKET, monkey.getUuid(), o.getMoney(),
							o.getStatus(), o.getCreatetime(), sdf));
				}
			}
		}
			break;

		case ORDER_HISTORY_MARRY: {
			TMarryOrderExample example = new TMarryOrderExample();
			example.or().andUseridEqualTo(userId);
			example.setOrderByClause("createTime DESC");
			example.setOffset(offset);
			example.setLimit(num);
			List<TMarryOrder> orders = marryOrderMapper.selectByExample(example);
			if (null == orders || orders.isEmpty()) {
				return ret;
			}
			SimpleDateFormat sdf = dateUtil.getDateFormat();
			for (TMarryOrder o : orders) {
				int monkeyId = o.getMonkeyid();
				Monkey monkey = getMonkey(monkeyId);
				if (null != monkey) {
					ret.add(new MonkeyOrder(monkeyId, MONKEY_STATUS_MARRY, monkey.getUuid(), o.getMoney(),
							o.getStatus(), o.getCreatetime(), sdf));
				}
			}
		}

		default:
			break;
		}
		return ret;
	}

	public Monkey getMonkey(int id) {
		try {
			Monkey monkey = monkeyCache.get(id);

			// 检查喂食时间
			SimpleDateFormat sdf = dateUtil.getSimpleDateFormat();
			String dataString = sdf.format(new Date());
			if (!monkey.getFeedTime().equals(dataString)) {
				monkey.setFeedCount(0);
				monkey.setFeedMoney(0);
			}
			return monkey;
		} catch (Exception e) {
			return null;
		}
	}

	public String getMonkeyUuid(int id) {
		Monkey monkey = getMonkey(id);
		if (null == monkey) {
			return null;
		}
		return monkey.getUuid();
	}

	public MonkeyDetailData getMonkeyDetail(int userId, int monkeyId) {
		User user = userService.getUser(userId);
		if (null == user) {
			logger.info("get monkey detail user error");
			return null;
		}

		Monkey monkey = getMonkey(monkeyId);
		if (!monkey.isInitFeed()) {
			if (!initFeed(userId, monkey)) {
				logger.info("get monkey detail init feed error");
				return null;
			}
		}
		if (!monkey.isInitBonus()) {
			if (!initBonus(userId, monkey)) {
				logger.info("get monkey detail init bonus error");
				return null;
			}
		}
		if (!monkey.isInitFamily()) {
			if (!initFamily(monkey)) {
				logger.info("get monkey detail init family error");
				return null;
			}
		}
		if (!monkey.isInitSynthesise()) {
			if (!initSynthesise(userId, monkey)) {
				logger.info("get monkey detail init synthesise error");
				return null;
			}
		}
		SimpleDateFormat sdf = dateUtil.getDateFormat();

		User user1 = userService.getUser(monkey.getUserId());
		return new MonkeyDetailData(monkey, user1, sdf);
	}

	public int updateMonkey(int monkeyId, TMonkey monkey) {
		TMonkeyExample example = new TMonkeyExample();
		example.or().andMonkeyidEqualTo(monkeyId);
		example.setLimit(1);
		return monkeyMapper.updateByExampleSelective(monkey, example);
	}

	public boolean initFeed(int userId, Monkey monkey) {
		SimpleDateFormat sdf = dateUtil.getDateFormat();

		// 初始化喂食记录
		int max = webConfig.getInt("feed.view.max");
		TUserFeedExample example = new TUserFeedExample();
		example.or().andUseridEqualTo(userId).andMonkeyidEqualTo(monkey.getId());
		example.setLimit(max);
		example.setOrderByClause("createTime DESC");
		List<TUserFeed> feeds = userFeedMapper.selectByExample(example);
		if (null != feeds && !feeds.isEmpty()) {
			List<MonkeyFeed> feedList = monkey.getFeeds();
			for (TUserFeed feed : feeds) {
				feedList.add(new MonkeyFeed(feed, sdf));
			}
		}
		monkey.setInitFeed(true);
		return true;
	}

	public boolean initBonus(int userId, Monkey monkey) {
		// 初始化喂食记录
		int max = webConfig.getInt("bonus.view.max");
		TMonkeyBonusExample example = new TMonkeyBonusExample();
		example.or().andUseridEqualTo(userId).andMonkeyidEqualTo(monkey.getId());
		example.setLimit(max);
		example.setOrderByClause("createTime DESC");
		List<TMonkeyBonus> bonuses = monkeyBonusMapper.selectByExample(example);
		if (null != bonuses && !bonuses.isEmpty()) {
			SimpleDateFormat sdf = dateUtil.getDateFormat();
			List<MonkeyBonus> bonuses1 = monkey.getBonuses();
			for (TMonkeyBonus bonus : bonuses) {
				bonuses1.add(new MonkeyBonus(bonus, sdf));
			}
		}
		monkey.setInitBonus(true);
		return true;
	}

	public boolean initFamily(Monkey monkey) {
		// 找到自己
		SimpleDateFormat sdf = dateUtil.getDateFormat();
		List<MonkeyReproduct> monkeyFamilies = monkey.getFamilies();
		TMonkeyReproductExample example = new TMonkeyReproductExample();
		example.or().andSonidEqualTo(monkey.getId());
		example.setLimit(1);
		List<TMonkeyReproduct> reproducts = monkeyReproductMapper.selectByExample(example);
		if (null != reproducts && !reproducts.isEmpty()) {
			for (TMonkeyReproduct reproduct : reproducts) {
				int dadId = reproduct.getDadid();
				int momId = reproduct.getMomid();
				int sonId = reproduct.getSonid();
				monkeyFamilies.add(new MonkeyReproduct(reproduct, getMonkeyUuid(dadId), getMonkeyUuid(momId),
						getMonkeyUuid(sonId), sdf));
			}
		}

		// 没有父母的情况下生成一条记录
		if (monkeyFamilies.isEmpty()) {
			TMonkeyReproduct reproduct = new TMonkeyReproduct();
			reproduct.setDadid(0);
			reproduct.setMomid(0);
			reproduct.setSonid(monkey.getId());
			reproduct.setCreatetime(monkey.getCreateTime());
			monkeyFamilies.add(new MonkeyReproduct(reproduct, "", "", getMonkeyUuid(monkey.getId()), sdf));
		}

		// 找父亲
		example = new TMonkeyReproductExample();
		example.or().andDadidEqualTo(monkey.getId());
		reproducts = monkeyReproductMapper.selectByExample(example);
		if (null != reproducts && !reproducts.isEmpty()) {
			for (TMonkeyReproduct reproduct : reproducts) {
				int dadId = reproduct.getDadid();
				int momId = reproduct.getMomid();
				int sonId = reproduct.getSonid();
				monkeyFamilies.add(new MonkeyReproduct(reproduct, getMonkeyUuid(dadId), getMonkeyUuid(momId),
						getMonkeyUuid(sonId), sdf));
			}
		}

		// 找母亲
		example = new TMonkeyReproductExample();
		example.or().andMomidEqualTo(monkey.getId());
		reproducts = monkeyReproductMapper.selectByExample(example);
		if (null != reproducts && !reproducts.isEmpty()) {
			for (TMonkeyReproduct reproduct : reproducts) {
				int dadId = reproduct.getDadid();
				int momId = reproduct.getMomid();
				int sonId = reproduct.getSonid();
				monkeyFamilies.add(new MonkeyReproduct(reproduct, getMonkeyUuid(dadId), getMonkeyUuid(momId),
						getMonkeyUuid(sonId), sdf));
			}
		}

		monkey.setInitFamily(true);
		return true;
	}

	public boolean initSynthesise(int userId, Monkey monkey) {
		SimpleDateFormat sdf = dateUtil.getDateFormat();

		// 初始化合成记录
		int max = webConfig.getInt("synthesise.view.max");
		TUserSynthesiseExample example = new TUserSynthesiseExample();
		example.or().andUseridEqualTo(userId).andMonkeyidEqualTo(monkey.getId());
		example.setLimit(max);
		example.setOrderByClause("createTime DESC");
		List<TUserSynthesise> synthesises = userSynthesiseMapper.selectByExample(example);
		if (null != synthesises && !synthesises.isEmpty()) {
			List<MonkeySynthesise> synthesiseList = monkey.getSynthesises();
			for (TUserSynthesise synthesise : synthesises) {
				synthesiseList.add(new MonkeySynthesise(synthesise, sdf));
			}
		}
		monkey.setInitSynthesise(true);
		return true;
	}
	
	private void addMonkeyCache(Monkey monkey) {
		monkeyCache.put(monkey.getId(), monkey);
	}

    public void removeMonkeyCache(Integer key) {  
        monkeyCache.invalidate(key);
    }
	
	private void initMonkeyIndex() {
		// 获取最大id
		monkeyIndex = webConfig.getInt("monkey.id.start");

		TMonkeyExample example = new TMonkeyExample();
		example.setOrderByClause("monkeyId desc");
		example.setLimit(1);

		List<TMonkey> monkeys = monkeyMapper.selectByExample(example);
		if (null != monkeys && !monkeys.isEmpty()) {
			int id = monkeys.get(0).getMonkeyid();
			if (id > monkeyIndex) {
				monkeyIndex = id;
			}
		}
		logger.info("set monkey index:{}", monkeyIndex);
	}

	private void initCache() {
		monkeyCache = CacheBuilder.newBuilder().recordStats().maximumSize(webConfig.getInt("monkey.cache.maxSize"))
				.expireAfterAccess(webConfig.getInt("monkey.cache.expireAfterAccess"), TimeUnit.HOURS)
				.expireAfterWrite(webConfig.getInt("monkey.cache.expireAfterWrite"), TimeUnit.MINUTES)
				.removalListener(new RemovalListener<Integer, Monkey>() {
					@Override
					public void onRemoval(RemovalNotification<Integer, Monkey> notification) {
						Monkey monkey = notification.getValue();
						if (null != monkey) {
							logger.info("monkey has removed. uid:{}", notification.getKey());
						}
					}
				}).build(new CacheLoader<Integer, Monkey>() {
					@Override
					public Monkey load(Integer id) {
						try {
							logger.info("load monkey from db:{}", id);
							TMonkeyExample example = new TMonkeyExample();
							example.or().andMonkeyidEqualTo(id);
							example.setLimit(1);
							List<TMonkey> monkeys = monkeyMapper.selectByExample(example);
							if (null == monkeys || monkeys.isEmpty()) {
								logger.error("load monkey null");
								return null;
							}

							// 关联玩家
							Monkey monkey = new Monkey(monkeys.get(0));
							TUserMonkeyExample example1 = new TUserMonkeyExample();
							example1.or().andMonkeyidEqualTo(id);
							example1.setLimit(1);
							List<TUserMonkey> userMonkeys = userMonkeyMapper.selectByExample(example1);
							if (null != userMonkeys && !userMonkeys.isEmpty()) {
								TUserMonkey userMonkey = userMonkeys.get(0);
								User user = userService.getUser(userMonkey.getUserid());
								if (null != user) {
									monkey.setUserInfo(userMonkey.getUserid());
								}
								monkey.setStatus(userMonkey.getStatus());

								// 初始喂食次数
								TMonkeyFeedExample example2 = new TMonkeyFeedExample();
								example2.or().andMonkeyidEqualTo(id);
								example2.setLimit(1);
								List<TMonkeyFeed> monkeyFeeds = monkeyFeedMapper.selectByExample(example2);
								if (null != monkeyFeeds && !monkeyFeeds.isEmpty()) {
									TMonkeyFeed monkeyFeed = monkeyFeeds.get(0);

									SimpleDateFormat sdf = dateUtil.getSimpleDateFormat();
									String dataString = sdf.format(new Date());
									if (monkeyFeed.getFeedtime().equals(dataString)) {
										monkey.setFeedCount(monkeyFeed.getCount());
										monkey.setFeedMoney(monkeyFeed.getMoney());
									}
									monkey.setFeedTime(monkeyFeed.getFeedtime());
								}
							}
							return monkey;
						} catch (Exception e) {
							logger.error("load monkey error:{}", e);
							return null;
						}
					}
				});
	}
}
